home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / dcache.zip / DCACHE.ASM next >
Assembly Source File  |  1988-10-11  |  55KB  |  1,036 lines

  1. ;==========================================================================
  2. ;  DCACHE.COM - A fixed disk cache for the IBM Personal Computer.
  3. ;  PC Magazine, Vol 7 # 17
  4. ;--------------------------------------------------------------------------
  5. CODE          SEGMENT PARA PUBLIC 'CODE'
  6.               ASSUME CS:CODE
  7.               ORG    2CH
  8. ENV_SEG       DW     ?                      ;Segment of the environment block
  9.               ORG    80H
  10. TAIL_LENGTH   DB     ?                      ;Length of the command tail
  11.  
  12.               ORG    100H
  13. ENTRY:        JMP    MAIN_ENTRY
  14. ;--------------------------------------------------------------------------
  15. ; Data Area
  16. ;--------------------------------------------------------------------------
  17. PROGRAM       DB     'DCACHE 1.0 (c) 1988 Ziff Communications Co.',13,10
  18.               DB     'PC Magazine ',254,' Douglas Boling',13,10,'$',26
  19.  
  20. ENABLED       DB     1                      ;0 = cache disabled, 1 = enabled
  21. EMS_FLAG      DB     0                      ;use EMS ram flag, 1 = use EMS
  22. EMS_HANDLE    DW     0                      ;handle for EMS memory.
  23.  
  24. ADDR_MASK     DW     001EH                  ;Default mask set for 64K cache
  25. SIZE_MASK     DW     0
  26. EMS_MASK      DW     0                      ;used to sel. the proper EMS page
  27.  
  28. DISK_NUM      DB     80H                    ;number of fixed disk to cache
  29. PAGE_SIZE     DB     8                      ;size of cache page
  30. MAX_HEAD      DW     ?                      ;maximum value of head parameter
  31. MAX_SECTOR    DW     ?                      ;maximum value of sector
  32. MAX_SEGMENT   DW     ?                      ;last segment of data cache
  33.  
  34. DOSBOFFSET    DW     ?                      ;offset of dos data buffer
  35. DOSBSEGMENT   DW     ?                      ;sector of dos data buffer
  36. NUM_OF_SEC    DB     ?                      ;number of sectors requested
  37. DISK_FUNCT    DB     ?                      ;function requested
  38. SECTOR_NUM    DW     ?                      ;sector parameter from dos call
  39. HEAD_NUM      DB     ?                      ;head parameter
  40. CYLINDER_NUM  DW     ?                      ;cylinder parameter
  41.  
  42. SEGMENT_PTR   DW     0                      ;pointers into the cache
  43. PAGE_PTR      DW     0
  44. LOG_SEC_HIGH  DW     0                      ;Logical sector number of disk
  45. LOG_SEC_LOW   DW     0                      ;  request.
  46. LAST_BAD_PAGE DW     -1                     ;stores the last page that
  47.                                             ;contained an error
  48. LOOKUPTABLE   DW     OFFSET DATA_START      ;offset of lookup table
  49. CACHE_SEGMENT DW     0                      ;segment of cache data
  50.  
  51. OLD_DISK_INT  LABEL  DWORD                  ;old bios interrupt 13h vector
  52. OLD_INT13H    DW     2 DUP (?)
  53. ;-----------------------------------------------------------------------------
  54. ; This routine intercepts the bios disk calls.
  55. ; Entry: ah - disk function      (All other registers specific to disk read.)
  56. ;        al - number of sectors                es:bx - pointer to data buffer
  57. ;        ch - Cylinder number                     dh - Head number
  58. ;        cl - 7,6 Cyl. high. 5-0 sector number    dl - drive number
  59. ;-----------------------------------------------------------------------------
  60. DISK_INT      PROC   FAR
  61.               ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
  62.               CMP    CS:ENABLED,0           ;See if cache enabled
  63.               JE     SKIP_CACHE
  64.               CMP    DL,CS:DISK_NUM         ;See if the correct disk
  65.               JNE    SKIP_CACHE
  66.               STI                           ;Allow interrupts
  67.               CMP    AH,2                   ;If any other function besides
  68.               JE     CACHE_IT               ;  read or write, reset cache.
  69.               CMP    AH,3
  70.               JE     CACHE_IT1
  71.               CMP    AH,1                   ;If just checking the last status
  72.               JE     SKIP_CACHE             ;  skip cache, but don't reset.
  73. RESET_CMD:
  74.               PUSH   ES                     ;If the command is not a simple
  75.               PUSH   CS                     ;  read, write, or status, assume
  76.               POP    ES                     ;  the worst and clear the lookup
  77.               ASSUME ES:CODE                ;  table.
  78.               CALL   RESET_CACHE
  79.               POP    ES
  80.               ASSUME ES:NOTHING
  81. SKIP_CACHE:
  82.               JMP    CS:OLD_DISK_INT        ;jmp to bios disk routine.
  83. ;--------------------------------------------------------------------------
  84. ;Compute the logical sector number from the cylinder, head, and sector.
  85. ;--------------------------------------------------------------------------
  86. CACHE_IT:
  87.               CMP    AL,CS:PAGE_SIZE        ;For disk read, cache reads of
  88.               JA     SKIP_CACHE             ;  a page or less.
  89. CACHE_IT1:
  90.               PUSH   DS                     ;save registers
  91.               PUSH   DI
  92.               PUSH   SI
  93.               PUSHF
  94.               PUSH   AX
  95.               PUSH   BX
  96.               PUSH   CX
  97.               PUSH   DX
  98.               PUSH   CS                     ;set ds to code segment
  99.               POP    DS
  100.               ASSUME DS:CODE
  101. ;--------------------------------------------------------------------------
  102. ;Store calling parameters.
  103. ;--------------------------------------------------------------------------
  104.               MOV    DOSBOFFSET,BX          ;save dos pointer to its data
  105.               MOV    DOSBSEGMENT,ES         ;  buffer.
  106.               MOV    BX,CX                  ;copy cx
  107.               AND    BX,003FH               ;strip all but the sector number
  108.               MOV    SECTOR_NUM,BX          ;save sector number
  109.               MOV    HEAD_NUM,DH            ;save head number
  110.               MOV    NUM_OF_SEC,AL          ;save the number of sectors needed
  111.               MOV    DISK_FUNCT,AH          ;save function called.
  112. ;--------------------------------------------------------------------------
  113. ;Compute logical sector number from the cylinder, head, and sector parameters.
  114. ;--------------------------------------------------------------------------
  115.               XCHG   CL,CH                  ;create full 10 bit cylinder num.
  116.               ROL    CH,1                   ;  the top 2 bits are in ch bits
  117.               ROL    CH,1                   ;  7 and 6. roll them into bits
  118.               AND    CH,03H                 ;  1 and 2.
  119.               MOV    CYLINDER_NUM,CX        ;save the cylinder number
  120.               MOV    AX,CX                  ;copy cylinder number for multiply
  121.               MOV    BL,DH                  ;get head number out of dx
  122.               MUL    MAX_HEAD               ;multiply cylinder to make room
  123.               XOR    BH,BH                  ;clear high byte of head value
  124.               ADD    AX,BX                  ;add in head.
  125.               MUL    MAX_SECTOR             ;multiply by max sector value
  126.               ADD    AX,SECTOR_NUM          ;add sector number
  127.               ADC    DX,0                   ;propigate carry.
  128.               MOV    LOG_SEC_HIGH,DX        ;save logical sector number
  129.               MOV    LOG_SEC_LOW,AX
  130. ;--------------------------------------------------------------------------
  131. ;Store values needed later.
  132. ;--------------------------------------------------------------------------
  133.               MOV    BH,AL
  134.               SHL    BH,1
  135.               AND    BX,3E00H
  136.               MOV    PAGE_PTR,BX            ;save page index
  137.               AND    BH,30H
  138.               MOV    SI,BX                  ;save page index for cache load
  139. ;--------------------------------------------------------------------------
  140. ;Point the segment register to the proper DOS memory block
  141. ;--------------------------------------------------------------------------
  142.               MOV    BX,AX                  ;copy logical sector low
  143.               MOV    CL,5
  144.               SHL    BX,CL                  ;Convert logical sector number to
  145.               AND    BX,SIZE_MASK           ;  cache page index
  146.               ADD    BX,CACHE_SEGMENT
  147.               MOV    SEGMENT_PTR,BX         ;save segment